package tp.pr4;

//import tp.pr3.instructions.exceptions.InstructionExecutionException;
import tp.pr4.instructions.exceptions.InstructionExecutionException;
import tp.pr4.items.*;

public class NavigationModule {
	private City aCity;	
	private Place currentPlace;	
	private Direction direction;
	
	
	
	/**
	 * Parametrized constructor
	 * @param aCity
	 * @param initialPlace
	 */
	public NavigationModule(City aCity, Place initialPlace){
		this.currentPlace = initialPlace;
		this.aCity = aCity;

	}	
	/**
	 * Returns true if the current place is the spaceship
	 * @return
	 */
	public boolean atSpaceship(){
		return this.currentPlace.isSpaceship();
	}
	/**
	 * sets the initial heading direction
	 * @param heading
	 */
	public void initHeading(Direction heading){
		this.direction = heading;
	}
	/**
	 * rotates the robot to the direction given
	 * @param rotation
	 */
	public void rotate(Rotation rotation){
		//guarda en el últimos estado la última dirección
		//status.setLastDirection(this.direction);
		if(rotation.equals(Rotation.LEFT)){//a la izquierda
			this.direction = this.direction.getLeft();							
		}else if(rotation.equals(Rotation.RIGHT)){//a la derecha
			this.direction = this.direction.getRight();						
		}
	}
	/**
	 * returns the current heading direction
	 * @return
	 */
	public Direction getCurrentHeading(){
		return this.direction;
	}
	/**
	 * returns the current place
	 * @return
	 */
	public Place getCurrentPlace(){
		return this.currentPlace;
	}
	/**
	 * sets the current place for the robot
	 * @param pl
	 */
	public void setCurrentPlace(Place pl){
		this.currentPlace = pl;
	}
	/**
	 * drops an item @ the current place
	 * @param it
	 */
	public void dropItemAtCurrentPlace(Item it){
		this.getCurrentPlace().dropItem(it);		
	}
	/**
	 * returns an item with the given id if it exists in the current place
	 * @param id
	 * @return
	 */
	public Item pickItemFromCurrentPlace(String id){
		if(this.currentPlace.getInventory().containsItem(id)){
			return this.currentPlace.getInventory().pickItem(id);
		}else{
			return null;
		}
	}
	/**
	 * moves the robot to the nextplace if possible
	 * @throws InstructionExecutionException
	 */
	public void move() throws InstructionExecutionException{								
		
			System.out.print("WALL·E says: Moving in direction "+this.getCurrentHeading().name()+Main.LINE_SEPARATOR);
			Street nxtst = this.aCity.lookForStreet(this.currentPlace, this.direction);
			if(nxtst != null){
				if(!nxtst.isOpen()){
					throw new InstructionExecutionException();
				}
				Place nxtplc = nxtst.nextPlace(this.getCurrentPlace());
				if(nxtplc != null){
					this.setCurrentPlace(nxtplc);//cambia el lugar actual por el siguiente
				}else{
					throw new InstructionExecutionException();
				}
			}else{
				throw new InstructionExecutionException();
			}
		
	}
	/**
	 * @return the aCity
	 */
	public City getaCity() {
		return aCity;
	}
	/**
	 * returns the street the robot is heading to
	 * @return
	 */
	public Street getHeadingStreet() {
		return this.aCity.lookForStreet(this.currentPlace, this.direction);
	}	
	/**
	 * Muestra la situaciÃ³n actual de WALLÂ·E
	 */
	public String showLocation(){
		return showPlaceInfo(this.getCurrentPlace());
	}
	
	public String showPlaceInfo(Place pl){
		String ret = pl.toString();
		if(pl.getInventory().numberOfItems()>0){
			ret += "The place contains these objects:"+Main.LINE_SEPARATOR+
			pl.getInventory().listItems();
		}else{
			ret += "The place is empty. There are no objects to pick";
		}
		return ret;
	}
	
	/**
	 * Returns current direction of the robot on a string
	 */
	public String showDirection(){
		return "WALL·E is looking at direction "+this.getCurrentHeading().name();
		
	}
	/**
	 * sets the direction
	 * @param dir
	 */
	public void setDirection(Direction dir){
		this.direction = dir;
	}
}
